using Microsoft.EntityFrameworkCore;
using DaoHang.Data;
using DaoHang.Models;

namespace DaoHang.Services
{
    /// <summary>
    /// 分类服务实现类，处理分类相关的业务逻辑
    /// </summary>
    public class CategoryService : ICategoryService
    {
        private readonly ApplicationDbContext context;
        private readonly ILogger<CategoryService> logger;

        /// <summary>
        /// 构造函数，注入依赖服务
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="logger">日志记录器</param>
        public CategoryService(ApplicationDbContext context, ILogger<CategoryService> logger)
        {
            this.context = context;
            this.logger = logger;
        }

        /// <summary>
        /// 获取所有分类列表，按排序顺序展示
        /// </summary>
        /// <returns>分类列表</returns>
        public async Task<List<Category>> GetAllCategoriesAsync()
        {
            try
            {
                return await context.Categories
                    .OrderBy(c => c.SortOrder)
                    .ThenBy(c => c.Name)
                    .ToListAsync();
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取所有分类列表时发生错误");
                throw;
            }
        }

        /// <summary>
        /// 根据ID获取分类详情
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <returns>分类信息</returns>
        public async Task<Category?> GetCategoryByIdAsync(int id)
        {
            try
            {
                return await context.Categories
                    .Include(c => c.Websites)
                    .FirstOrDefaultAsync(c => c.Id == id);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "根据ID {Id} 获取分类详情时发生错误", id);
                throw;
            }
        }

        /// <summary>
        /// 添加新分类
        /// </summary>
        /// <param name="category">分类信息</param>
        /// <returns>添加的分类</returns>
        public async Task<Category> AddCategoryAsync(Category category)
        {
            try
            {
                // 检查分类名称是否已存在
                if (await IsCategoryNameExistsAsync(category.Name))
                {
                    throw new InvalidOperationException($"分类名称 '{category.Name}' 已存在");
                }

                category.CreateTime = DateTime.Now;
                
                context.Categories.Add(category);
                await context.SaveChangesAsync();
                
                logger.LogInformation("成功添加分类: {Name}", category.Name);
                return category;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "添加分类时发生错误: {Name}", category.Name);
                throw;
            }
        }

        /// <summary>
        /// 创建新分类
        /// </summary>
        /// <param name="category">分类信息</param>
        /// <returns>是否创建成功</returns>
        public async Task<bool> CreateCategoryAsync(Category category)
        {
            try
            {
                var result = await AddCategoryAsync(category);
                return result != null;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 更新分类信息
        /// </summary>
        /// <param name="category">分类信息</param>
        /// <returns>更新的分类</returns>
        public async Task<Category> UpdateCategoryAsync(Category category)
        {
            try
            {
                var existingCategory = await context.Categories.FindAsync(category.Id);
                if (existingCategory == null)
                {
                    throw new InvalidOperationException($"未找到ID为 {category.Id} 的分类");
                }

                // 检查分类名称是否已存在（排除当前分类）
                if (await IsCategoryNameExistsAsync(category.Name, category.Id))
                {
                    throw new InvalidOperationException($"分类名称 '{category.Name}' 已存在");
                }

                // 更新属性
                existingCategory.Name = category.Name;
                existingCategory.Description = category.Description;
                existingCategory.SortOrder = category.SortOrder;

                await context.SaveChangesAsync();
                
                logger.LogInformation("成功更新分类: {Name}", category.Name);
                return existingCategory;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "更新分类时发生错误: ID {Id}", category.Id);
                throw;
            }
        }

        /// <summary>
        /// 删除分类
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <returns>删除是否成功</returns>
        public async Task<bool> DeleteCategoryAsync(int id)
        {
            try
            {
                var category = await context.Categories
                    .Include(c => c.Websites)
                    .FirstOrDefaultAsync(c => c.Id == id);
                
                if (category == null)
                {
                    return false;
                }

                // 检查分类下是否有网站
                if (category.Websites.Any())
                {
                    throw new InvalidOperationException($"分类 '{category.Name}' 下还有 {category.Websites.Count} 个网站，无法删除");
                }

                context.Categories.Remove(category);
                await context.SaveChangesAsync();
                
                logger.LogInformation("成功删除分类: {Name} (ID: {Id})", category.Name, id);
                return true;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "删除分类时发生错误: ID {Id}", id);
                throw;
            }
        }

        /// <summary>
        /// 检查分类名称是否已存在
        /// </summary>
        /// <param name="name">分类名称</param>
        /// <param name="excludeId">排除的分类ID（用于更新时检查）</param>
        /// <returns>是否已存在</returns>
        public async Task<bool> IsCategoryNameExistsAsync(string name, int? excludeId = null)
        {
            try
            {
                var query = context.Categories.Where(c => c.Name == name);
                
                if (excludeId.HasValue)
                {
                    query = query.Where(c => c.Id != excludeId.Value);
                }

                return await query.AnyAsync();
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "检查分类名称是否存在时发生错误: {Name}", name);
                throw;
            }
        }

        /// <summary>
        /// 获取分类下的网站数量
        /// </summary>
        /// <param name="categoryId">分类ID</param>
        /// <returns>网站数量</returns>
        public async Task<int> GetWebsiteCountByCategoryAsync(int categoryId)
        {
            try
            {
                return await context.Websites.CountAsync(w => w.CategoryId == categoryId);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取分类下网站数量时发生错误: CategoryId {CategoryId}", categoryId);
                throw;
            }
        }
    }
} 